package com.hxy.es.service;

import com.alibaba.fastjson.JSON;

import com.hxy.es.domain.BookVo;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: ES文档操作
 * @program: springbootTest
 * @author: HCY
 * @create: 2022/04/19 14:48
 */
@Component
public class EsDocService {


    @Autowired
    private RestHighLevelClient esClient;

    /**
     * 新增文档数据 map为参数
     * @param indexName
     * @param map  文档的字段 key-value 形式
     * @throws IOException
     */
    public void addDocByMap(String indexName,Map<String, Object> map) throws IOException {
        // id为自己设置的
        // IndexRequest request = new IndexRequest().id("1").source(map);

        IndexRequest request = new IndexRequest(indexName).source(map);
        IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
        System.out.println(response.getId());
    }

    /**
     * 新增文档数据 实体作为参数
     * @param indexName 索引名称
     * @param bookVo  实体
     * @throws IOException
     */
    public void addDocByDomain(String indexName, BookVo bookVo) throws IOException {
        String data = JSON.toJSONString(bookVo);
        IndexRequest request = new IndexRequest(indexName).source(data, XContentType.JSON);
        IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
        System.out.println(response.getId());
    }

    /**
     * 根据id修改文档，其实和添加文档是一个方法，有传入文档中存在的id就是更新，不存在的就是新增
     * @param indexName
     * @param bookVo
     * @param id
     * @throws IOException
     */
    public void updateDocByDomain(String indexName, BookVo bookVo,String id) throws IOException {
        String data = JSON.toJSONString(bookVo);
        IndexRequest request = new IndexRequest(indexName).id(id).source(data, XContentType.JSON);
        IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
        System.out.println(response.getId());
    }

    /**
     * 根据id查询文档
     * @param indexName
     * @param id
     * @throws IOException
     */
    public void selectDocById(String indexName,String id) throws IOException {
        //设置查询的索引、文档
        GetRequest indexRequest = new GetRequest(indexName,id);
        GetResponse response = esClient.get(indexRequest, RequestOptions.DEFAULT);
        System.out.println(response.getSourceAsString());
    }

    /**
     * 根据id删除文档
     * @param indexName
     * @param id
     * @throws IOException
     */
    public void delDocById(String indexName,String id) throws IOException {
        //设置要删除的索引、文档
        DeleteRequest deleteRequest = new DeleteRequest(indexName,id);
        DeleteResponse response = esClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(response.getId());
    }

    /**
     * 按条件删除文档
     * @param indexName
     * @throws IOException
     */
    public void delDocByWhere(String indexName) throws IOException {
        //设置要删除的索引
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(indexName);
        //设置条件，可设置多个
        deleteByQueryRequest.setQuery(new TermQueryBuilder("book", "测试2"));
        deleteByQueryRequest.setQuery(new TermQueryBuilder("author", "作者1"));
        // 设置并行
        deleteByQueryRequest.setSlices(2);
        // 设置超时
        deleteByQueryRequest.setTimeout(TimeValue.timeValueMinutes(2));
        BulkByScrollResponse response = esClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
        System.out.println(response.getStatus().getDeleted());
    }

    /**
     * 多文档进行逻辑批量处理 比如同时：1. 删除一条记录
     *                             2. 添加一条新记录
     *                             3. 修改一条记录
     * @param indexName
     * @throws IOException
     */
    public void docBulklogic(String indexName) throws IOException {
        // 创建bulkrequest对象，整合所有操作
        BulkRequest bulkRequest =new BulkRequest();
        //添加对应操作
        //1. 删除5号记录
        DeleteRequest deleteRequest=new DeleteRequest(indexName,"5");
        //2. 添加6号记录
        Map<String, Object> map=new HashMap<>();
        map.put("name","六号");
        IndexRequest indexRequest=new IndexRequest(indexName).id("6").source(map);
        //3. 修改3号记录 名称为 “三号”
        Map<String, Object> mapUpdate=new HashMap<>();
        mapUpdate.put("book","三号");
        UpdateRequest updateRequest=new UpdateRequest(indexName,"3").doc(mapUpdate);
        //4.假如批处理对象
        bulkRequest.add(deleteRequest);
        bulkRequest.add(indexRequest);
        bulkRequest.add(updateRequest);
        //5.执行批量操作
        BulkResponse response = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }

    /**
     * 批量导入数据
     * @param indexName
     * @param bookList
     * @throws IOException
     */
    public void docAddBatchData(String indexName,List<BookVo> bookList) throws IOException {
        //1.bulk导入
        BulkRequest bulkRequest = new BulkRequest();

        //2.1 循环goodsList，创建IndexRequest添加数据
        for (BookVo books : bookList) {
            //将goods对象转换为json字符串
            String data = JSON.toJSONString(books);
            IndexRequest indexRequest = new IndexRequest(indexName).source(data,XContentType.JSON);
            bulkRequest.add(indexRequest);

        }
        BulkResponse response = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());

    }
}
